/*  mudmap - A tool to create and organize user side maps for MUD games
 *  Copyright (C) 2012  Neop (aka moemneop, email: mneop@web.de)
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
 *  for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, see <http://www.gnu.org/licenses/>.
 */

/*  File description
 *
 *  Methods and functions for drawing the map in an Gtkdrawinarea can be found in this file
 */

#pragma once

#include <sstream>
#include <iomanip>
#include <list>
#include <cmath>

#include <gtk/gtk.h>

#include "worldmgr.h"
#include "tk.h"
#include "dialogs.h"

using std::stringstream;
using std::list;
using std::map;
using std::hash;

namespace dia{

void goto_place(int plid, void* mapd);

class coord{
    public:
        int layer;
        float x, y;
        coord(int lay, float px, float py){
            layer = lay;
            x = px;
            y = py;
        }
        bool operator!=(coord c){
            if(layer != c.layer || x != c.x || y != c.y) return true;
            return false;
        }
};

class mapdrawing{
    public:
        mapdrawing(string world_file, GtkWidget *notebook, GtkWidget *window);
        virtual ~mapdrawing();

        shared_ptr<world> get_world();
        GtkWidget *get_content();
        GtkWidget *get_label();

        void goto_home(bool apv = true);
        void goto_place(int pl, bool apv = true);
        void goto_pos(int x, int y, int lay, bool apv = true);
        void goto_previous();
        void goto_next();
        void set_home();
        void place_call_list_add_cur_place();

        void draw();
        void save_layer_as_png(string file, int layer);
        void save_screen_as_png(string file);

        pair<int, int> get_tile_pos(int mouse_x, int mouse_y);

        static void mi_area_new_func(GtkWidget *parent, gpointer user_data);
        static void close_func(GtkButton *button, gpointer user_data);

        bool close;
        static bool *mode_debug;
        static bool *mode_small_tiles;
        static bool *mode_aspect_ratio;
        static bool *mode_way_lines_show;
        static bool *mode_way_lines_curved;

        static shared_ptr<mapdrawing> *cur_mapd;

        void save_meta();
        void load_meta();

        shared_ptr<place> way_connect_pl1;
        string way_connect_pl1_dir;

        float cur_center_x, cur_center_y;
        int cur_layer;

    protected:
        GtkWidget *label, *content, *notebook, *window;

        unsigned get_tile_width();
        unsigned get_tile_height();

        bool mouse_l, mouse_r;
        float mouse_x_bef, mouse_y_bef;
        float wdtw, hdth;

        bool save_cur_screen_as_png;
        string image_file;

        shared_ptr<world> cur_world;

        int context_tile_x, context_tile_y;
        shared_ptr<place> context_place;

        shared_ptr<place> tooltip_place;

        vector<char**> show_context_menu_dir_vec;

        shared_ptr<layer> copy_layer;
        int copy_ofs_x, copy_ofs_y;

        bool get_exit_pos(string dir, int *x, int *y);
        pair<float, float> get_exit_normal(string dir);

        list<coord> place_call_list;
        list<coord>::iterator place_call_list_num;
        void place_call_list_add(int lay, float x, float y);

        void draw(cairo_t *cr, guint width, guint height, float cur_center_x, float cur_center_y);

        void init_gui();
        void show_context_menu(GdkEventButton *event);

        void cut_place(shared_ptr<place> pl);
        void cut_add_place(shared_ptr<place> pl);
        bool paste_places(int x, int y);

        static gboolean buttonpressfunc(GtkWidget *widget, GdkEventButton *event, gpointer data);
        static gboolean buttonreleasefunc(GtkWidget *widget, GdkEventButton *event, gpointer data);
        static gboolean leavenotifyfunc(GtkWidget *widget, GdkEventButton *event, gpointer data);
        static gboolean pointermotionfunc(GtkWidget *widget, GdkEventMotion *event, gpointer data);
        static gboolean drawfunc(GtkWidget *widget, cairo_t *cr, gpointer data);
        static gboolean tooltipfunc(GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, gpointer data);

        static void mi_place_new_func(GtkMenuItem *menuitem, gpointer user_data);
        static void mi_place_edit_func(GtkMenuItem *menuitem, gpointer user_data);
        static void mi_place_edit_marked_func(GtkMenuItem *menuitem, gpointer user_data);
        static void mi_place_delete_func(GtkMenuItem *menuitem, gpointer user_data);
        static void mi_place_cut_func(GtkMenuItem *menuitem, gpointer user_data);
        static void mi_paste_place_func(GtkMenuItem *menuitem, gpointer user_data);
        static void mi_subarea_new_func(GtkMenuItem *menuitem, gpointer user_data);
        static void mi_subarea_new_with_layer_func(GtkMenuItem *menuitem, gpointer user_data);
        static void mi_subarea_goto_func(GtkMenuItem *menuitem, gpointer user_data);
        static void mi_subarea_remove_func(GtkMenuItem *menuitem, gpointer user_data);
        static void mi_way_add_func(GtkMenuItem *menuitem, gpointer user_data);
        static void mi_way_add_another_func(GtkMenuItem *menuitem, gpointer user_data);
        static void mi_way_add_automatic_func(GtkMenuItem *menuitem, gpointer user_data);
        static void mi_way_remove_func(GtkMenuItem *menuitem, gpointer user_data);
        static void mi_comments_edit_func(GtkWidget *parent, gpointer user_data);
        static void mi_area_edit_func(GtkWidget *parent, gpointer user_data);
        static void mi_insert_row_func(GtkWidget *parent, gpointer user_data);
        static void mi_insert_column_func(GtkWidget *parent, gpointer user_data);
        static void mi_remove_row_func(GtkWidget *parent, gpointer user_data);
        static void mi_remove_column_func(GtkWidget *parent, gpointer user_data);
};

}
